using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;
namespace Microsoft.Phone.Controls.Maps.Core
{
	internal static class TouchHelper
	{
		private static bool isEnabled;
		private static readonly Dictionary<UIElement, TouchHandlers> currentHandlers = new Dictionary<UIElement, TouchHandlers>();
		private static readonly Dictionary<int, UIElement> currentCaptures = new Dictionary<int, UIElement>();
		private static readonly Dictionary<int, TouchPoint> currentTouchPoints = new Dictionary<int, TouchPoint>();
		public static bool AreAnyTouches
		{
			get
			{
				return TouchHelper.currentTouchPoints.get_Count() != 0;
			}
		}
		public static bool Capture(this TouchDevice touchDevice, UIElement element)
		{
			if (touchDevice == null)
			{
				throw new ArgumentNullException("element");
			}
			UIElement uIElement;
			TouchHandlers touchHandlers;
			if (TouchHelper.currentCaptures.TryGetValue(touchDevice.get_Id(), ref uIElement) && !object.ReferenceEquals(uIElement, element) && TouchHelper.currentHandlers.TryGetValue(uIElement, ref touchHandlers))
			{
				EventHandler<TouchEventArgs> lostTouchCapture = touchHandlers.LostTouchCapture;
				TouchPoint touchPoint;
				if (lostTouchCapture != null && TouchHelper.currentTouchPoints.TryGetValue(touchDevice.get_Id(), ref touchPoint))
				{
					lostTouchCapture.Invoke(uIElement, new TouchEventArgs(touchPoint));
				}
			}
			if (element != null)
			{
				TouchHelper.currentCaptures.set_Item(touchDevice.get_Id(), element);
			}
			else
			{
				TouchHelper.currentCaptures.Remove(touchDevice.get_Id());
			}
			return true;
		}
		public static void AddHandlers(UIElement element, TouchHandlers handlers)
		{
			if (element == null)
			{
				throw new ArgumentNullException("element");
			}
			if (handlers == null)
			{
				throw new ArgumentNullException("handlers");
			}
			TouchHelper.currentHandlers.set_Item(element, handlers);
			TouchHelper.EnableInput(true);
		}
		public static void RemoveHandlers(UIElement element)
		{
			if (element == null)
			{
				throw new ArgumentNullException("element");
			}
			TouchHelper.currentHandlers.Remove(element);
			if (TouchHelper.currentHandlers.get_Count() == 0)
			{
				TouchHelper.EnableInput(false);
			}
		}
		private static void EnableInput(bool enable)
		{
			if (enable)
			{
				if (!TouchHelper.isEnabled)
				{
					TouchHelper.EnableInput();
					TouchHelper.isEnabled = true;
					return;
				}
			}
			else
			{
				if (TouchHelper.isEnabled)
				{
					TouchHelper.DisableInput();
					TouchHelper.isEnabled = false;
				}
			}
		}
		private static void EnableInput()
		{
			Touch.add_FrameReported(new TouchFrameEventHandler(TouchHelper.TouchFrameReported));
		}
		private static void DisableInput()
		{
			Touch.remove_FrameReported(new TouchFrameEventHandler(TouchHelper.TouchFrameReported));
			TouchHelper.currentCaptures.Clear();
			TouchHelper.currentHandlers.Clear();
			TouchHelper.currentTouchPoints.Clear();
		}
		private static void TouchFrameReported(object sender, TouchFrameEventArgs e)
		{
			UIElement rootVisual = Application.get_Current().get_RootVisual();
			if (rootVisual == null)
			{
				return;
			}
			Collection<int> collection = new Collection<int>();
			using (IEnumerator<TouchPoint> enumerator = e.GetTouchPoints(rootVisual).GetEnumerator())
			{
				while (enumerator.MoveNext())
				{
					TouchPoint current = enumerator.get_Current();
					int id = current.get_TouchDevice().get_Id();
					collection.Add(id);
					switch (current.get_Action())
					{
					case 1:
						TouchHelper.HitTestAndRaiseDownEvent(rootVisual, current);
						TouchHelper.currentTouchPoints.set_Item(id, current);
						break;
					case 2:
						TouchHelper.currentTouchPoints.set_Item(id, current);
						break;
					case 3:
					{
						UIElement uIElement;
						TouchHelper.currentCaptures.TryGetValue(id, ref uIElement);
						if (uIElement != null)
						{
							TouchHelper.RaiseUpEvent(uIElement, current);
							current.get_TouchDevice().Capture(null);
							uIElement = null;
						}
						TouchHelper.currentTouchPoints.Remove(id);
						break;
					}
					}
				}
			}
			Collection<int> collection2 = new Collection<int>();
			using (Dictionary<int, TouchPoint>.KeyCollection.Enumerator enumerator2 = TouchHelper.currentTouchPoints.get_Keys().GetEnumerator())
			{
				while (enumerator2.MoveNext())
				{
					int current2 = enumerator2.get_Current();
					if (!collection.Contains(current2))
					{
						collection2.Add(current2);
					}
				}
			}
			using (IEnumerator<int> enumerator3 = collection2.GetEnumerator())
			{
				while (enumerator3.MoveNext())
				{
					int current3 = enumerator3.get_Current();
					TouchHelper.currentTouchPoints.Remove(current3);
				}
			}
			if (TouchHelper.currentTouchPoints.get_Count() == 0)
			{
				TouchHelper.currentCaptures.Clear();
			}
			TouchHelper.RaiseCapturedReportEvent(rootVisual);
		}
		private static void RaiseCapturedReportEvent(UIElement root)
		{
			using (Dictionary<UIElement, TouchHandlers>.Enumerator enumerator = TouchHelper.currentHandlers.GetEnumerator())
			{
				while (enumerator.MoveNext())
				{
					KeyValuePair<UIElement, TouchHandlers> current = enumerator.get_Current();
					EventHandler<TouchReportedEventArgs> capturedTouchReported = current.get_Value().CapturedTouchReported;
					if (capturedTouchReported != null)
					{
						UIElement key = current.get_Key();
						if (key != null)
						{
							GeneralTransform generalTransform;
							try
							{
								generalTransform = root.TransformToVisual(key);
							}
							catch (ArgumentException)
							{
								continue;
							}
							List<Point> list = new List<Point>();
							using (Dictionary<int, UIElement>.Enumerator enumerator2 = TouchHelper.currentCaptures.GetEnumerator())
							{
								while (enumerator2.MoveNext())
								{
									KeyValuePair<int, UIElement> current2 = enumerator2.get_Current();
									TouchPoint touchPoint;
									if (object.ReferenceEquals(current2.get_Value(), current.get_Key()) && TouchHelper.currentTouchPoints.TryGetValue(current2.get_Key(), ref touchPoint))
									{
										list.Add(generalTransform.Transform(touchPoint.get_Position()));
									}
								}
							}
							capturedTouchReported.Invoke(current.get_Key(), new TouchReportedEventArgs(list));
						}
					}
				}
			}
		}
		private static void HitTestAndRaiseDownEvent(UIElement root, TouchPoint touchPoint)
		{
			Point position = root.TransformToVisual(null).Transform(touchPoint.get_Position());
			using (IEnumerator<UIElement> enumerator = TouchHelper.InputHitTest(root, position).GetEnumerator())
			{
				while (enumerator.MoveNext())
				{
					UIElement current = enumerator.get_Current();
					TouchHandlers touchHandlers;
					if (TouchHelper.currentHandlers.TryGetValue(current, ref touchHandlers))
					{
						EventHandler<TouchEventArgs> touchDown = touchHandlers.TouchDown;
						if (touchDown != null)
						{
							touchDown.Invoke(current, new TouchEventArgs(touchPoint));
							break;
						}
					}
				}
			}
		}
		private static IEnumerable<UIElement> InputHitTest(UIElement root, Point position)
		{
			TouchHelper.<InputHitTest>d__0 <InputHitTest>d__ = new TouchHelper.<InputHitTest>d__0(-2);
			<InputHitTest>d__.<>3__root = root;
			<InputHitTest>d__.<>3__position = position;
			return <InputHitTest>d__;
		}
		private static void RaiseUpEvent(UIElement element, TouchPoint touchPoint)
		{
			TouchHandlers touchHandlers;
			if (TouchHelper.currentHandlers.TryGetValue(element, ref touchHandlers))
			{
				EventHandler<TouchEventArgs> capturedTouchUp = touchHandlers.CapturedTouchUp;
				if (capturedTouchUp != null)
				{
					capturedTouchUp.Invoke(element, new TouchEventArgs(touchPoint));
				}
			}
		}
	}
}
